#pragma once

#include <QVector>
#include <osgGA\CameraManipulator>
#include "controlcenter_global.h"
#include "scene.h"
#include "datatypedefine.h"
#include "manipulatordefine.h"

namespace CoreBase
{
	class ActorBase;
}

namespace VrDataCore
{
	class EnvironmentLayerActor;
}

namespace osgViewer
{
	class View;
}

namespace ControlCenter
{
	class CONTROLCENTER_EXPORT ManipulatorBase:public osgGA::CameraManipulator
	{
	public:
		ManipulatorBase();

		virtual void setOperatorObjectVector(QVector<CoreBase::ActorBase*> objvector);
		virtual void addOperatorObject(CoreBase::ActorBase* obj);
		virtual QVector<CoreBase::ActorBase*>	getOperatorObjectVector();
		virtual void setLookAt(const osg::Vec3& eye,const osg::Vec3& center,const osg::Vec3& up,float distance,bool rightaway);
		virtual void setLookAt(const osg::Vec3& vec,const osg::Vec3& rota,float upangle,float sideangle,float distancevalue
			,bool rightaway){}
		virtual void initManipulatorStart(const osg::Vec3& eye,const osg::Vec3& center,const osg::Vec3& up);
		virtual void getLookAt(osg::Vec3& eye,osg::Vec3& center,osg::Vec3& up,float& distance);
		virtual void computeNewPositionPerFrame(){}
		virtual void computeInverseMatrixPerFrame(){}
		virtual void setToolAction(ActionData* action);
		virtual void setOperateObjectType(int type){_operateObjType = type;}
		virtual void enableManipulator(){}
		virtual void disenableManipulator(){}
		void openCameraInSky(bool open){_cameraInSky = open;}
		void clearOperatorObjectVector()
		{
			_operatorObjectVector.clear();
		}
		void useCollisionCamera(bool use);
		virtual void flushMouseEventStack();
		virtual void flushKeyEventStack();
		void setSpeed(float multiplier)
		{
			_multiplier = multiplier;
		}
		void setViewType(int type)
		{
			_viewType = type;
			switch(_viewType)
			{
			case 1:
				_camera_min_height = 2;
				_camera_max_height = 6000;
				break;
			case 0:
				_camera_min_height = 1;
				_camera_max_height = 99999;
				break;
			default:
				break;
			}
		}
		virtual void moveCenterTo(double x,double y){}
	protected:
		void addMouseEvent(const osgGA::GUIEventAdapter& ea);
		void addKeyEvent(const osgGA::GUIEventAdapter& ea);
		bool graphWindowHaveFocus(const int x,const int y);
		int intersectionTestSphereWithSegment(double segx1, double segy1, double segz1,
		double segx2, double segy2, double segz2,double sx, double sy, double sz, double r,
		double *ix, double *iy, double *iz);
		bool testInSky(const osg::Matrixd& before,const osg::Matrixd& after,osg::Vec3& intersectz,bool& movein);
		~ManipulatorBase();
		QVector<CoreBase::ActorBase*>					_operatorObjectVector;
		bool											_useCollisionCamera;
		bool											_lostFocus;
		bool											_usePickManager;
		bool											_boolFocusInGraphWin;
		osg::ref_ptr<const osgGA::GUIEventAdapter>		_ga_t1;
		osg::ref_ptr<const osgGA::GUIEventAdapter>		_ga_t0;
		osg::ref_ptr<const osgGA::GUIEventAdapter>		_key_t1;
		osg::ref_ptr<const osgGA::GUIEventAdapter>		_key_t0;
		float											_multiplier;
		float											_maxradius;
		int												_viewType;
		int												_action;
		int												_operateObjType;
		bool											_cameraInSky;
		osgViewer::View*								_view;
		VrDataCore::EnvironmentLayerActor*				_environmentLayer;
		int												_camera_min_height;
		int												_camera_max_height;
	};
}